package com.zyz.common.utils.html;

import com.zyz.common.utils.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * HTML工具类
 *
 * @author zyz
 * @date 2021年3月4日
 */
public class HtmlKit {

    private static final String API_EDITOR_PIC = "api-editor-pic";

    private static final String SLASH = "/";

    /**
     * processAllSrc 处理的所有标签
     */
    private static final String[] CSSQUERYS = {"img[src]", "video[src]", "source[src]", "audio[src]"};

    /**
     * 富文本资源路径添加basePath
     *
     * @param content
     * @param basePath
     * @return String
     * @author zyz
     * @date 2021年2月25日
     */
    public static String getHtmlContent(String content, String basePath) {
        if (StringUtils.isAnyBlank(content, basePath)) {
            return content;
        }
        return HtmlKit.addBashPath(content, basePath, CSSQUERYS);
    }

    /**
     * 富文本资源路径移除basePath
     *
     * @param content
     * @param basePath
     * @return String
     * @author zyz
     * @date 2021年2月25日
     */
    public static String getDbHtmlContent(String content, String basePath) {
        if (StringUtils.isAnyBlank(content, basePath)) {
            return content;
        }
        return HtmlKit.removeBashPath(content, basePath, CSSQUERYS);
    }

    /**
     * 获取文件HTTP全路径
     *
     * @param path
     * @param basePath
     * @return String
     * @author zyz
     * @date 2021年2月25日
     */
    public static String getFileHttpAllPath(String path, String basePath) {
        if (StringUtils.isAnyBlank(path, basePath)) {
            return path;
        }
        if (isHttpUrl(path)) {
            return path;
        }
        return removeEndSlash(basePath) + SLASH + removeStartSlash(path);
    }

    /**
     * 文件全路径去除basePath
     *
     * @param path
     * @param basePath
     * @return String
     * @author zyz
     * @date 2021年3月2日
     */
    public static String getDbFilePath(String path, String basePath) {
        if (StringUtils.isAnyBlank(path, basePath)) {
            return path;
        }
        if (!isHttpAllPath(basePath, path)) {
            return path;
        }
        return removeBasePath(basePath, path);
    }

    /**
     * 获取指定HTML标签的指定属性的值
     *
     * @param source  要匹配的源文本
     * @param element 标签名称
     * @param attr    标签的属性名称
     * @return 属性值列表
     */
    public static List<String> matchEleAttr(String source, String element, String attr) {
        List<String> result = new ArrayList<String>(16);
        if (StringUtils.isAnyBlank(source, element, attr)) {
            return result;
        }
        String reg = "<" + element + "[^<>]*?\\s" + attr + "=['\"]?(.*?)['\"]?(\\s.*?)?/?>";
        Matcher m = Pattern.compile(reg).matcher(source);
        while (m.find()) {
            String r = m.group(1);
            result.add(r);
        }
        return result;
    }

    private static String addBashPath(String content, String basePath, String[] cssQuerys) {
        Document document = Jsoup.parse(content);
        document.setBaseUri(basePath);
        return resetDocument(document, basePath, cssQuerys, true);
    }

    private static String removeBashPath(String content, String basePath, String[] cssQuerys) {
        basePath = removeEndSlash(basePath);
        Document document = Jsoup.parse(content);
        return resetDocument(document, basePath, cssQuerys, false);
    }

    private static String resetDocument(Document document, String basePath, String[] cssQuerys, boolean isFullPath) {
        for (String cssQuery : cssQuerys) {
            Elements elements = document.select(cssQuery);
            for (Element el : elements) {
                String imgUrl = el.attr("src");
                if (imgUrl == null) {
                    continue;
                }
                imgUrl = imgUrl.trim();
                if (isFullPath) {
                    // 图片添加class api-editor-pic
                    if (Objects.equals("img[src]", cssQuery)) {
                        el.addClass(API_EDITOR_PIC);
                        el.removeAttr("title");
                        el.removeAttr("alt");
                    }
                    if (isHttpUrl(imgUrl)) {
                        continue;
                    }
                    el.attr("src", getFileHttpAllPath(imgUrl, basePath));
                } else {
                    if (!isHttpAllPath(basePath, imgUrl)) {
                        continue;
                    }
                    el.attr("src", removeBasePath(basePath, imgUrl));
                }
            }
        }
        return document.getElementsByTag("body").html();
    }

    private static String removeBasePath(String basePath, String imgUrl) {
        return imgUrl.replace(removeEndSlash(basePath), "");
    }

    private static String removeStartSlash(String url) {
        if (url.startsWith(SLASH)) {
            return removeStartSlash(url.substring(1, url.length()));
        }
        return url;
    }

    private static String removeEndSlash(String url) {
        if (url.endsWith(SLASH)) {
            return removeEndSlash(url.substring(0, url.length() - 1));
        }
        return url;
    }

    private static boolean isHttpAllPath(String basePath, String path) {
        return isHttpUrl(path) && path.startsWith(basePath);
    }

    private static boolean isHttpUrl(String url) {
        return url.startsWith("http://") || url.startsWith("https://");
    }

}